package com.zero.clinic.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zero.clinic.pojo.*;
import com.zero.clinic.service.DeptService;
import com.zero.clinic.service.JobService;
import com.zero.clinic.service.UserService;
import com.zero.clinic.utils.Constant;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Controller
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private DeptService deptService;
    @Resource
    private JobService jobService;

    /**
     * @function 登录
     * @param request
     * @param m
     * @return
     */
    @RequestMapping("/login")
    public String login(HttpServletRequest request, Model m){
        //1.从request中获取shiroLoginFailure属性的值
        String shiroLoginFailure = (String) request.getAttribute("shiroLoginFailure");
        System.out.println("shiroLoginFailure: " + shiroLoginFailure);
        //2.根据shiroLoginFailure的值来判断是否认证成功，如果认证失败则返回数据给前端
        if (UnknownAccountException.class.getName().equals(shiroLoginFailure)){
            m.addAttribute("errMsg", "用户名不存在");
        } else if (IncorrectCredentialsException.class.getName().equals(shiroLoginFailure)){
            m.addAttribute("errMsg", "密码错误");
        }
        return "forward:/login.jsp";
    }

    /**
     * @function 进入员工管理模块
     * @return
     */
    @RequiresPermissions("user:userPage")
    @RequestMapping("/userPage")
    public String userPage(){
        return "userPage";
    }

    /**
     * @function 员工列表
     * @param pageNum
     * @param pageSize
     * @param keywords
     * @return
     */
    @ResponseBody
    @RequiresPermissions("user:list")
    @RequestMapping("/list")
    public PageInfo<User> userList(@RequestParam(defaultValue = "1") int pageNum,
                                   @RequestParam(defaultValue = "10") int pageSize, String keywords){
        System.out.println("pageNum: " + pageNum + ";pageSize: " + pageSize);
        // 0.开始启用PageHelper
        PageHelper.startPage(pageNum, pageSize);
        // 1.查出所有的User信息
        UserExample example = new UserExample();
        // 2 根据搜索关键词查询
        if (StringUtils.isNotBlank(keywords)){
            // 2.1 根据真实姓名查询
            UserExample.Criteria criteria1 = example.createCriteria();
            criteria1.andRealnameLike("%"+ keywords +"%");
            // 2.2 根据受教育程度查询
            UserExample.Criteria criteria2 = example.or();
            criteria2.andEducationIs(keywords);
            // 2.3 根据科室查询
            UserExample.Criteria criteria3= example.or();
            criteria3.andDeptNameLike("%"+ keywords +"%");
            // 2.4 根据职务查询
            UserExample.Criteria criteria4= example.or();
            criteria4.andJobNameLike("%"+ keywords +"%");
            // 2.5 根据上级查询
            UserExample.Criteria criteria5= example.or();
            criteria5.andSuperiorNameLike("%"+ keywords +"%");
        }
        List<User> users = userService.selectByExample(example);
        // 3.以PageInfo对象返回给前端
        PageInfo<User> pageInfo = new PageInfo<>(users);
        return pageInfo;
    }

    /**
     * @function 编辑员工页面
     * @param userId
     * @param m
     * @return
     */
    @RequestMapping("/edit")
    public String userEdit(Long userId, Model m){

        // 1.如果前端页面需要更新员工信息，则会传一个需要更新的userId过来。这里需要通过userId查出更新信息后共享给前端页面
        if (userId != null) {
            User user = userService.selectByPrimaryKey(userId);
            m.addAttribute("user",user);
        }

        // 2.将科室信息查询出来后共享到前端页面
        DeptExample example1 = new DeptExample();
        List<Dept> depts = deptService.selectByExample(example1);
        m.addAttribute("depts",depts);
        // 3.将职位信息查询出来后共享到前端页面
        JobExample example2 = new JobExample();
        List<Job> jobs = jobService.selectByExample(example2);
        m.addAttribute("jobs",jobs);
        // 4.将所有人员信息查询出来后作为上级信息共享到前端页面
        UserExample example3 = new UserExample();
        List<User> superiors = userService.selectByExample(example3);
        m.addAttribute("superiors",superiors);
        return "userEdit";
    }

    /**
     * @function 新增员工
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping("/insert")
    @RequiresPermissions("user:insert")
    public MessageObject userInsert(User user){
        //1.为需要插入的数据设置盐，并将加盐加散列3次后的密码放进user对象中
        String salt = UUID.randomUUID().toString().substring(0, 5);
        Md5Hash md5Hash = new Md5Hash(user.getPassword(), salt, 3);
        user.setPassword(md5Hash.toString());
        user.setSalt(salt);
        //2.设置用户创建时间
        user.setCreateTime(new Date());
        //3.插入数据
        System.out.println(user);
        int row = userService.insert(user);
        if (row > 0) {
            return MessageObject.createMo(1,"新增数据成功");
        }
        return MessageObject.createMo(0,"新增数据失败，请联系技术人员");
    }

    /**
     * @function 更新员工
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping("/update")
    @RequiresPermissions("user:update")
    public MessageObject userUpdate(User user){
        //1.为需要插入的数据设置盐，并将加盐加散列3次后的密码放进user对象中
        String salt = UUID.randomUUID().toString().substring(0, 5);
        Md5Hash md5Hash = new Md5Hash(user.getPassword(), salt, 3);
        user.setPassword(md5Hash.toString());
        user.setSalt(salt);
        //2.设置用户修改时间
        user.setUpdateTime(new Date());
        //3.更新数据
        System.out.println("需要更新的数据" + user);
        int row = userService.updateByPrimaryKeySelective(user);
        if (row > 0) {
            return MessageObject.createMo(1,"更新数据成功");
        }
        return MessageObject.createMo(0,"更新数据失败，请联系技术人员");
    }

    /**
     * @function 检查用户名是否重复
     * @param username
     * @return
     */
    @ResponseBody
    @RequestMapping("/checkUsername")
    @RequiresPermissions("user:checkUsername")
    public boolean userCheckUsername(String username){
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo(username);
        List<User> users = userService.selectByExample(example);
        return users.size() > 0 ? false : true;
    }

    /**
     * @function 显示员工详细信息
     * @param userId
     * @param m
     * @return
     */
    @RequestMapping("/detail")
    public String userDetail(Long userId, Model m){
        // 1.通过前端页面传过来的userId查询对应的员工信息，并共享给前端页面
        if (userId != null) {
            User user = userService.selectByPrimaryKey(userId);
            m.addAttribute("user",user);
        }
        // 2.将科室信息查询出来后共享到前端页面
        DeptExample example1 = new DeptExample();
        List<Dept> depts = deptService.selectByExample(example1);
        m.addAttribute("depts",depts);
        // 3.将职位信息查询出来后共享到前端页面
        JobExample example2 = new JobExample();
        List<Job> jobs = jobService.selectByExample(example2);
        m.addAttribute("jobs",jobs);
        // 4.将所有人员信息查询出来后作为上级信息共享到前端页面
        UserExample example3 = new UserExample();
        List<User> superiors = userService.selectByExample(example3);
        m.addAttribute("superiors",superiors);

        return "userDetail";
    }

    /**
     * @function 删除员工
     * @param userId
     * @return
     */
    @ResponseBody
    @RequestMapping("/delete")
    @RequiresPermissions("user:delete")
    public MessageObject userDelete(Long userId){
        //1.删除数据前判断该用户下面是否还有下属，如果有则不能删除
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();
        criteria.andSuperiorIdEqualTo(userId);
        List<User> users = userService.selectByExample(example);
        if (users.size() > 0) {
            return MessageObject.createMo(0,"该用户还有下属，不能直接删除");
        }

        //2.根据userId删除数据
        int row = userService.deleteByPrimaryKey(userId);
        if (row > 0){
            return MessageObject.createMo(1,"删除数据成功");
        }
        return MessageObject.createMo(0,"删除数据失败");
    }

    /**
     * @function 批量删除员工
     * @param userIds
     * @return
     */
    @ResponseBody
    @RequestMapping("/batchdel")
    @RequiresPermissions("user:batchdel")
    public MessageObject userBatchDelete(String userIds){
        //1.删除数据前判断用户下面是否还有下属，如果有则不能删除
        String[] userIdsArr = userIds.split(",");
        for (String userId : userIdsArr) {
            UserExample example = new UserExample();
            UserExample.Criteria criteria = example.createCriteria();
            criteria.andSuperiorIdEqualTo(Long.parseLong(userId));
            List<User> users = userService.selectByExample(example);
            if (users.size() > 0) {
                return MessageObject.createMo(0,"被删除的用户还有下属，不能直接删除");
            }
        }

        //2.根据userIdsArr删除数据
        int row = userService.deleteByIds(userIdsArr);
        if (row > 0){
            return MessageObject.createMo(1,"删除数据成功");
        }
        return MessageObject.createMo(0,"删除数据失败");
    }

    /**
     * @function 根据科室id获取到该科室的医生
     * @param deptId
     * @return
     */
    @ResponseBody
    @RequestMapping("/getDoctorsByDeptId")
    public List<User> userGetDoctorsByDeptId(Long deptId){
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();
        criteria.andDeptIdEqualTo(deptId);
        criteria.andJobNameLike(Constant.JOB_NAME_DOCTOR);
        List<User> doctors = userService.selectByExample(example);
        return doctors;
    }

}
